#include "socketchannel.h"
#include "../coroutine_function.h"
#include <unistd.h>
#include <fcntl.h>
#include "tinyrpc/base/logger/logger.h"
#include "tinyrpc/net/eventloop.h"
#include "tinyrpc/net/coroutine_function.h"
namespace TinyRPC{

// 设置为非阻塞模式
SocketChannel::SocketChannel(int fd,  const INetAddress& peerAddress)
: AbstractChannel(fd)
, m_peerAddress(peerAddress)
, m_buf(new Buffer()){

    ::fcntl(m_fd->fd(), F_SETFL, O_NONBLOCK);
}
BufferPtr SocketChannel::read(){
   
    char buf[1024] = {0};
    int len = 0;
    // 循环读， 直到读完为止
    while (true)
    {
       len = coroutine_read(m_fd->fd(), buf, 1024);
       if(len < 0 ){
           LOG_ERROR<<"socket read error";
           break;
       }else if (len == 0){
           break;
       }else if(len < 1024){
            m_buf->append(buf, len);
            break;
       }else if(len >= 1024){
            m_buf->append(buf, len);
       }
    }

    return m_buf;
}
void SocketChannel::write(BufferPtr buffer){
 
    int sum = 0;
    // 循环读， 直到读完为止
    std::string buf = buffer->read();
    while (sum < buf.size())
    {
       int len = coroutine_write(m_fd->fd(), (const void*) buf.c_str() + sum, buf.size()-sum);
       sum += len;
    }
    deleteEvent(EventLoop::CurrentEventLoop());
}

void SocketChannel::write(const std::string & buffer){
 
    int sum = 0;
   
    while (sum < buffer.size())
    {
       int len = coroutine_write(m_fd->fd(), (const void*) buffer.c_str() + sum, buffer.size()-sum);
       sum += len;
    }
    deleteEvent(EventLoop::CurrentEventLoop());
}

SocketChannel::SocketChannel()
: m_sockFd(socket(AF_INET, SOCK_STREAM, 0))
, AbstractChannel(m_sockFd){


}
void SocketChannel::connect(const INetAddress& peerAddress){
    m_peerAddress = peerAddress;
    sockaddr_in addr = peerAddress.getSockAddr();
    socklen_t len = sizeof(addr);
    coroutine_connect(m_sockFd, (sockaddr *) &addr, len);
}

}
